home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 12 / Example 12.3 / app.cpp next >
Encoding:
C/C++ Source or Header  |  2006-08-01  |  6.8 KB  |  271 lines

  1. //////////////////////////////////////////////////////////////
  2. // Example 12.3: Particle Systems                            //
  3. // Written by: C. Granberg, 2006                            //
  4. //////////////////////////////////////////////////////////////
  5.  
  6. #include <windows.h>
  7. #include <d3dx9.h>
  8. #include "debug.h"
  9. #include "shader.h"
  10. #include "effect.h"
  11. #include "mesh.h"
  12. #include "particles.h"
  13.  
  14. class APPLICATION
  15. {
  16.     public:
  17.         APPLICATION();
  18.         HRESULT Init(HINSTANCE hInstance, int width, int height, bool windowed);
  19.         HRESULT Update(float deltaTime);
  20.         HRESULT Render();
  21.         HRESULT Cleanup();
  22.         HRESULT Quit();
  23.         DWORD FtoDword(float f){return *((DWORD*)&f);}
  24.  
  25.     private:
  26.         IDirect3DDevice9* m_pDevice; 
  27.         MESH m_floor;
  28.  
  29.         D3DLIGHT9 m_light;
  30.         HWND m_mainWindow;
  31.  
  32.         //Effects 
  33.         std::vector<EFFECT*> m_effects;
  34. };
  35.  
  36. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
  37. {
  38.     APPLICATION app;
  39.  
  40.     if(FAILED(app.Init(hInstance, 800, 600, true)))return 0;
  41.  
  42.     MSG msg;
  43.     memset(&msg, 0, sizeof(MSG));
  44.     int startTime = timeGetTime(); 
  45.  
  46.     while(msg.message != WM_QUIT)
  47.     {
  48.         if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  49.         {
  50.             ::TranslateMessage(&msg);
  51.             ::DispatchMessage(&msg);
  52.         }
  53.         else
  54.         {    
  55.             int t = timeGetTime();
  56.             float deltaTime = (t - startTime)*0.001f;
  57.  
  58.             app.Update(deltaTime);
  59.             app.Render();
  60.  
  61.             startTime = t;
  62.         }
  63.     }
  64.  
  65.     app.Cleanup();
  66.  
  67.     return msg.wParam;
  68. }
  69.  
  70. APPLICATION::APPLICATION()
  71. {
  72.     m_pDevice = NULL; 
  73.     m_mainWindow = 0;
  74.     srand(GetTickCount());
  75. }
  76.  
  77. HRESULT APPLICATION::Init(HINSTANCE hInstance, int width, int height, bool windowed)
  78. {
  79.     debug.Print("Application initiated");
  80.  
  81.     //Create Window Class
  82.     WNDCLASS wc;
  83.     memset(&wc, 0, sizeof(WNDCLASS));
  84.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  85.     wc.lpfnWndProc   = (WNDPROC)::DefWindowProc; 
  86.     wc.hInstance     = hInstance;
  87.     wc.lpszClassName = "D3DWND";
  88.  
  89.     //Register Class and Create new Window
  90.     RegisterClass(&wc);
  91.     m_mainWindow = CreateWindow("D3DWND", "Example 12.3: Particle Systems", WS_EX_TOPMOST, 0, 0, width, height, 0, 0, hInstance, 0); 
  92.     SetCursor(NULL);
  93.     ShowWindow(m_mainWindow, SW_SHOW);
  94.     UpdateWindow(m_mainWindow);
  95.  
  96.     //Create IDirect3D9 Interface
  97.     IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  98.  
  99.     if(d3d9 == NULL)
  100.     {
  101.         debug.Print("Direct3DCreate9() - FAILED");
  102.         return E_FAIL;
  103.     }
  104.  
  105.     //Check that the Device supports what we need from it
  106.     D3DCAPS9 caps;
  107.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
  108.  
  109.     //Hardware Vertex Processing or not?
  110.     int vp = 0;
  111.     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  112.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  113.     else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  114.  
  115.     //Check vertex & pixelshader versions
  116.     if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
  117.     {
  118.         debug.Print("Warning - Your graphic card does not support vertex and pixelshaders version 2.0");
  119.     }
  120.  
  121.     //Set D3DPRESENT_PARAMETERS
  122.     D3DPRESENT_PARAMETERS d3dpp;
  123.     d3dpp.BackBufferWidth            = width;
  124.     d3dpp.BackBufferHeight           = height;
  125.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
  126.     d3dpp.BackBufferCount            = 1;
  127.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
  128.     d3dpp.MultiSampleQuality         = 0;
  129.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
  130.     d3dpp.hDeviceWindow              = m_mainWindow;
  131.     d3dpp.Windowed                   = windowed;
  132.     d3dpp.EnableAutoDepthStencil     = true; 
  133.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
  134.     d3dpp.Flags                      = 0;
  135.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  136.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
  137.  
  138.     //Create the IDirect3DDevice9
  139.     if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_mainWindow,
  140.                                  vp, &d3dpp, &m_pDevice)))
  141.     {
  142.         debug.Print("Failed to create IDirect3DDevice9");
  143.         return E_FAIL;
  144.     }
  145.  
  146.     //Release IDirect3D9 interface
  147.     d3d9->Release();
  148.  
  149.     // Create m_light
  150.     ::ZeroMemory(&m_light, sizeof(m_light));
  151.     m_light.Type      = D3DLIGHT_DIRECTIONAL;
  152.     m_light.Ambient   = D3DXCOLOR(0.5, 0.5, 0.5, 1.0f);
  153.     m_light.Diffuse   = D3DXCOLOR(0.9, 0.9, 0.9, 1.0f);
  154.     m_light.Specular  = D3DXCOLOR(0.5, 0.5, 0.5, 1.0f);
  155.     D3DXVECTOR3 dir = D3DXVECTOR3(-1.0f, -1.0f, 0.0f);
  156.     D3DXVec3Normalize(&dir, &dir);
  157.     m_light.Direction = dir;    
  158.     m_pDevice->SetLight(0, &m_light);
  159.     m_pDevice->LightEnable(0, true);
  160.  
  161.     //Load resources
  162.     LoadEffectResources(m_pDevice);
  163.     LoadParticleResources(m_pDevice);
  164.  
  165.     m_floor.Load("meshes/floor.x", m_pDevice);
  166.  
  167.     //Set sampler state
  168.     for(int i=0;i<4;i++)
  169.     {
  170.         m_pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  171.         m_pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  172.         m_pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  173.     }
  174.  
  175.     m_effects.push_back(new MAGIC_SHOWER(m_pDevice, 1000, D3DXVECTOR3(0.0f, 9.0f, 0.0f)));
  176.     m_effects.push_back(new MAGIC_SHOWER(m_pDevice, 500, D3DXVECTOR3(10.0f, 7.0f, 0.0f)));
  177.     m_effects.push_back(new MAGIC_SHOWER(m_pDevice, 500, D3DXVECTOR3(-10.0f, 7.0f, 0.0f)));
  178.  
  179.     return S_OK;
  180. }
  181.  
  182. HRESULT APPLICATION::Update(float deltaTime)
  183. {
  184.     //Remove dead effects
  185.     std::vector<EFFECT*>::iterator i;
  186.     for(i=m_effects.begin();i != m_effects.end();)
  187.     {
  188.         if((*i)->isDead())
  189.         {
  190.             delete (*i);
  191.             m_effects.erase(i);
  192.         }
  193.         else 
  194.         {
  195.             (*i)->Update(deltaTime);
  196.             i++;
  197.         }
  198.     }
  199.  
  200.     //Keayboard input
  201.     if(KEYDOWN(VK_SPACE))
  202.     {
  203.     }
  204.     if(KEYDOWN(VK_RETURN))
  205.     {
  206.     }
  207.     else if(KEYDOWN(VK_ESCAPE))
  208.     {
  209.         Quit();
  210.     }
  211.  
  212.     return S_OK;
  213. }    
  214.  
  215. HRESULT APPLICATION::Render()
  216. {
  217.     // Clear the viewport
  218.     m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
  219.  
  220.     //Set camera
  221.     D3DXMATRIX view, proj, world, identity;
  222.     D3DXMatrixLookAtLH(&view, &D3DXVECTOR3(0.0f, 20.0f, -50.0f), &D3DXVECTOR3(0.0f, 3.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
  223.     D3DXMatrixPerspectiveFovLH(&proj, 0.4f, 1.33333f, 0.01f, 1000.0f);
  224.     D3DXMatrixIdentity(&identity);
  225.  
  226.     m_pDevice->SetTransform(D3DTS_VIEW, &view);
  227.     m_pDevice->SetTransform(D3DTS_PROJECTION, &proj);
  228.     m_pDevice->SetTransform(D3DTS_WORLD, &identity);
  229.  
  230.     // Begin the scene 
  231.     if(SUCCEEDED(m_pDevice->BeginScene()))
  232.     {            
  233.         m_pDevice->SetRenderState(D3DRS_LIGHTING, true);
  234.         m_floor.Render();
  235.  
  236.         //Render Effects
  237.         for(int i=0;i<m_effects.size();i++)
  238.             if(m_effects[i] != NULL)
  239.                 m_effects[i]->Render();
  240.  
  241.         // End the scene.
  242.         m_pDevice->EndScene();
  243.         m_pDevice->Present(0, 0, 0, 0);
  244.     }
  245.  
  246.     return S_OK;
  247. }
  248.  
  249. HRESULT APPLICATION::Cleanup()
  250. {
  251.     try
  252.     {
  253.         UnloadEffectResources();
  254.         UnloadParticleResources();
  255.  
  256.         m_floor.Release();
  257.         m_pDevice->Release();
  258.  
  259.         debug.Print("Application terminated");
  260.     }
  261.     catch(...){}
  262.  
  263.     return S_OK;
  264. }
  265.  
  266. HRESULT APPLICATION::Quit()
  267. {
  268.     ::DestroyWindow(m_mainWindow);
  269.     ::PostQuitMessage(0);
  270.     return S_OK;
  271. }